﻿using System;
using System.Collections.Generic;
using RentalSystem.Data.EF.Core;

namespace RentalSystem.Data.EF.Dao
{
    public class EFMoviesDao : IMoviesDao
    {
        #region Queries

        private static string GetByFileQuery;
        private static string GetByGuidQuery;
        private static string GetByTitleQuery;
        private static string ListQuery;

        #endregion

        private EFManager<Movies> manager;

        public EFMoviesDao(RentalDatabaseEntities repository)
        {
            ListQuery = "SELECT VALUE m FROM Movies AS m;";
            GetByGuidQuery = "SELECT VALUE m FROM Movies AS m WHERE m.MovieGuid = @Guid;";
            GetByTitleQuery = "SELECT VALUE m FROM Movies AS m WHERE m.MovieTitle = @Title;";
            GetByFileQuery = "SELECT VALUE m FROM Movies AS m WHERE m.MovieImageFileID = @FileId;";

            this.manager = new EFManager<Movies>(repository);
        }

        #region IDao1Key

        public Movies Add(Movies entity)
        {
            manager.Database.AddToMovies(entity);
            manager.Save();
            return entity;
        }

        public Movies Get(string id)
        {
            QueryParam[] parameters = new QueryParam[]
                {
                    new QueryParam("@Guid", id)
                };

            var movies = manager.SQLQueryToEntity(GetByGuidQuery, parameters);

            foreach (Movies movie in movies)
            {
                return movie;
            }

            return null;
        }

        public void Delete(string id)
        {
            manager.Database.Movies.DeleteObject(Get(id));
            manager.Save();
        }

        public void Delete(Movies entity)
        {
            Delete(entity.MovieGuid);
        }

        public void Update(Movies entity, uint fields)
        {
            Movies fromDb = Get(entity.MovieGuid);

            if (fromDb != null)
            {
                if ((fields & (uint)MovieFields.Director) == (uint)MovieFields.Director)
                    fromDb.MovieDirector = entity.MovieDirector;
                if ((fields & (uint)MovieFields.Duration) == (uint)MovieFields.Duration)
                    fromDb.MovieDuration = entity.MovieDuration;
                if ((fields & (uint)MovieFields.IssueDate) == (uint)MovieFields.IssueDate)
                    fromDb.MovieIssueDate = entity.MovieIssueDate;
                if ((fields & (uint)MovieFields.Publisher) == (uint)MovieFields.Publisher)
                    fromDb.MoviePublisher = entity.MoviePublisher;
                if ((fields & (uint)MovieFields.Title) == (uint)MovieFields.Title)
                    fromDb.MovieTitle = entity.MovieTitle;
                if ((fields & (uint)MovieFields.ImageFile) == (uint)MovieFields.ImageFile)
                {
                    if (entity.MovieImageFileID != null)
                    {
                        fromDb.MovieImageFileID = entity.MovieImageFileID;
                    }

                }

                manager.Save();
            }
        }

        public List<Movies> List()
        {
            List<Movies> list = new List<Movies>();

            var movies = manager.SQLQueryToEntity(ListQuery);

            foreach (Movies movie in movies)
            {
                list.Add(movie);
            }

            return list;
        }

        #endregion

        public Movies GetByTitle(string title)
        {
            QueryParam[] parameters = new QueryParam[]
                {
                    new QueryParam("@Title", title)
                };

            var movies = manager.SQLQueryToEntity(GetByTitleQuery, parameters);

            foreach (Movies movie in movies)
            {
                return movie;
            }

            return null;
        }

        public void DeleteAllMovieMovieKinds(string movieGuid)
        {
            Movies movie = Get(movieGuid);

            if (movie != null && movie.MovieMovieKinds != null)
            {
                List<MovieMovieKinds> toDelete = new List<MovieMovieKinds>();

                foreach (MovieMovieKinds mmk in movie.MovieMovieKinds)
                    toDelete.Add(mmk);
                foreach (MovieMovieKinds mmk in toDelete)
                    manager.Database.MovieMovieKinds.DeleteObject(mmk);

                manager.Save();
            }
        }

        public MovieMovieKinds AddMovieMovieKind(MovieMovieKinds kind)
        {
            manager.Database.AddToMovieMovieKinds(kind);
            manager.Save();
            return kind;
        }
        
        public void DeleteMovieImage(int fileId)
        {
            QueryParam[] parameters = new QueryParam[]
                {
                    new QueryParam("@FileId", fileId)
                };

            var movies = manager.SQLQueryToEntity(GetByFileQuery, parameters);
            
            foreach (Movies movie in movies)
            {
                movie.Files = null;
            }

            manager.Save();
        }
        
        public void DeleteMovieMovieKind(string movieGuid)
        {
            Movies movie = Get(movieGuid);

            if (movie != null && movie.MovieMovieKinds != null)
            {
                foreach (MovieMovieKinds kind in movie.MovieMovieKinds)
                {
                    manager.Database.MovieMovieKinds.DeleteObject(kind);
                }
            }
        }
    }
}
